home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: DZDisplay.c
- *
- * Contents: Handles the window and its contents.
- *
- * Copyright © 1996 Apple Computer, Inc.
- */
-
- #ifndef USE_DRAW_SPROCKET
- #define USE_DRAW_SPROCKET 1
- #endif
-
- #if USE_DRAW_SPROCKET
- #define USE_PIXMAP_DRAW_CONTEXT 1
- #endif
-
- #include <assert.h>
-
- #include <Fonts.h>
- #include <Quickdraw.h>
- #include <SegLoad.h>
- #include <Windows.h>
-
- #include <QD3D.h>
- #include <QD3DCamera.h>
- #include <QD3DDrawContext.h>
- #include <QD3DGroup.h>
- #include <QD3DLight.h>
- #include <QD3DMath.h>
- #include <QD3DRenderer.h>
- #include <QD3DShader.h>
- #include <QD3DView.h>
-
- #include "DZDisplay.h"
- #include "DZGame.h"
- #include "DZInput.h"
- #include "DZResource.h"
-
- #if USE_DRAW_SPROCKET
- #include "DrawSprocket.h"
- #endif
-
-
- #if USE_DRAW_SPROCKET
- static DSpContextReference gDisplayContext = NULL;
- #else
- static WindowPtr gDisplayWindow = NULL;
- #endif
-
- static Boolean gDisplayActive = false;
-
- static PicHandle gDisplayStartScreen = NULL;
-
- static TQ3ViewObject gDisplayView = NULL;
- static TQ3DrawContextObject gDisplayDrawContext = NULL;
- static TQ3RendererObject gDisplayRenderer = NULL;
- static TQ3CameraObject gDisplayCamera = NULL;
- static TQ3GroupObject gDisplayLightGroup = NULL;
- static TQ3LightObject gDisplayAmbientLight = NULL;
- static TQ3LightObject gDisplayDirectionalLight = NULL;
- static TQ3LightObject gDisplayPointLight = NULL;
- static TQ3ShaderObject gDisplayIllumination = NULL;
-
- //• To get around an Interactive Renderer bug wherein Q3Renderer_Sync
- //• crashes when called on a renderer that has not rendered.
- static Boolean gDisplayHasRendered = false;
-
-
- static void Display_RenderImage(
- void);
-
- static void Display_BeginQD(
- void);
-
- static void Display_EndQD(
- void);
-
- static void Display_GetImageArea(
- TQ3Area* outArea);
-
- static float Display_GetImageAspectRatio(
- void);
-
-
- /* =============================================================================
- * Display_Init (external)
- *
- * Creates the display window, initializes QD3D view etc. to draw in it.
- * ========================================================================== */
- void Display_Init(
- void)
- {
- OSStatus err = noErr;
- TQ3ViewAngleAspectCameraData viewAngleCameraData;
- TQ3PointLightData pointLightData;
- TQ3ColorRGB white = {1.0, 1.0, 1.0};
-
- // Grab the start screen
- gDisplayStartScreen = GetPicture(kPictID_StartScreen);
-
- // Create the view
- gDisplayView = Q3View_New();
-
- // Set up where to draw
- #if USE_DRAW_SPROCKET
- {
- DSpContextAttributes attributes;
- DSpContextAttributes actual;
-
- DSpStartup();
-
- // Create the display
- attributes.frequency = 0;
- attributes.displayWidth = 512;
- attributes.displayHeight = 384;
- attributes.reserved1 = 0;
- attributes.reserved2 = 0;
- attributes.colorNeeds = kDSpColorNeeds_Request;
- attributes.colorTable = NULL;
- attributes.contextOptions = 0; //• kDSpContextOption_QD3DAccel
- attributes.backBufferDepthMask = kDSpDepthMask_32 | kDSpDepthMask_16;
- attributes.displayDepthMask = kDSpDepthMask_32 | kDSpDepthMask_16;
- attributes.backBufferBestDepth = 16;
- attributes.displayBestDepth = 16;
- attributes.pageCount = 1;
- attributes.gameMustConfirmSwitch = false;
- attributes.reserved3[0] = 0;
- attributes.reserved3[1] = 0;
- attributes.reserved3[2] = 0;
- attributes.reserved3[3] = 0;
-
- err = DSpFindBestContext(&attributes, &gDisplayContext);
- if (err != noErr || gDisplayContext == NULL)
- {
- //• PUT UP AN ALERT INDICATING THAT THERE ISN'T A
- //• DEVICE GOOD ENOUGH TO RUN ON.
- ExitToShell();
- }
-
- DSpContext_Reserve(gDisplayContext, &attributes);
- DSpContext_FadeGammaOut(NULL, NULL);
- DSpContext_SetState(gDisplayContext, kDSpContextState_Active);
-
- Display_DrawContents();
-
- DSpContext_FadeGammaIn(NULL, NULL);
- DSpContext_GetAttributes(gDisplayContext, &actual);
-
- #if USE_PIXMAP_DRAW_CONTEXT
- {
- GWorldPtr theGWorld;
- PixMapHandle pixMapHandle;
- TQ3PixmapDrawContextData pixmapDrawContextData;
-
- // Create the pixmap draw context with the image pointing to our back buffer
- DSpContext_GetBackBuffer(gDisplayContext, kDSpBufferKind_Normal, &theGWorld);
- pixMapHandle = GetGWorldPixMap(theGWorld);
-
- pixmapDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- pixmapDrawContextData.drawContextData.clearImageColor.a = 1.0;
- pixmapDrawContextData.drawContextData.clearImageColor.r = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.g = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.b = 0.0;
- pixmapDrawContextData.drawContextData.paneState = kQ3False;
- pixmapDrawContextData.drawContextData.maskState = kQ3False;
- pixmapDrawContextData.drawContextData.doubleBufferState = kQ3True;
-
- pixmapDrawContextData.pixmap.image = GetPixBaseAddr(pixMapHandle);
- pixmapDrawContextData.pixmap.width = attributes.displayWidth;
- pixmapDrawContextData.pixmap.height = attributes.displayHeight;
- pixmapDrawContextData.pixmap.rowBytes = (*pixMapHandle)->rowBytes & 0x00003FFF;
- pixmapDrawContextData.pixmap.pixelSize = actual.displayBestDepth;
- pixmapDrawContextData.pixmap.bitOrder = kQ3EndianBig;
- pixmapDrawContextData.pixmap.byteOrder = kQ3EndianBig;
-
- switch (pixmapDrawContextData.pixmap.pixelSize)
- {
- case 16:
- pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB16;
- break;
-
- case 32:
- pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB32;
- break;
-
- default:
- assert(0);
- }
-
- gDisplayDrawContext = Q3PixmapDrawContext_New(&pixmapDrawContextData);
- }
- #else
- {
- TQ3MacDrawContextData macDrawContextData;
-
- // Create the mac draw context with the port pointing to our back buffer
- macDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- macDrawContextData.drawContextData.clearImageColor.a = 1.0;
- macDrawContextData.drawContextData.clearImageColor.r = 0.0;
- macDrawContextData.drawContextData.clearImageColor.g = 0.0;
- macDrawContextData.drawContextData.clearImageColor.b = 0.0;
- macDrawContextData.drawContextData.maskState = kQ3False;
- macDrawContextData.drawContextData.paneState = kQ3False;
- macDrawContextData.drawContextData.doubleBufferState = kQ3True;
- macDrawContextData.library = kQ3Mac2DLibraryNone;
- macDrawContextData.viewPort = NULL;
- macDrawContextData.grafPort = NULL;
-
- GetDisplayBackBuffer(gDisplayContext, &macDrawContextData.window);
-
- gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
- }
- #endif
- }
- #else
- {
- TQ3MacDrawContextData macDrawContextData;
-
- // Create the window
- gDisplayWindow = GetNewCWindow(kWindID_Display, NULL, (WindowPtr)(-1));
-
- // Create the draw context
- macDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- macDrawContextData.drawContextData.clearImageColor.a = 1.0;
- macDrawContextData.drawContextData.clearImageColor.r = 0.0;
- macDrawContextData.drawContextData.clearImageColor.g = 0.0;
- macDrawContextData.drawContextData.clearImageColor.b = 0.0;
- macDrawContextData.drawContextData.maskState = kQ3False;
- macDrawContextData.library = kQ3Mac2DLibraryNone;
- macDrawContextData.drawContextData.paneState = kQ3True;
- macDrawContextData.drawContextData.doubleBufferState = kQ3True;
- macDrawContextData.window = (CGrafPtr) gDisplayWindow;
-
- Display_GetImageArea(&macDrawContextData.drawContextData.pane);
-
- gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
- }
- #endif
-
- Q3View_SetDrawContext(gDisplayView, gDisplayDrawContext);
-
- // Create the renderer
- #if 1
- gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
- Q3InteractiveRenderer_SetDoubleBufferBypass(gDisplayRenderer, kQ3True);
- #else
- gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireframe);
- #endif
-
- Q3View_SetRenderer(gDisplayView, gDisplayRenderer);
-
- // Create the camera
- viewAngleCameraData.cameraData.placement.cameraLocation.x = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.y = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.z = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.x = 1.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.y = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.z = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.x = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.y = 1.0;
- viewAngleCameraData.cameraData.placement.upVector.z = 0.0;
- viewAngleCameraData.cameraData.range.hither = 0.2;
- viewAngleCameraData.cameraData.range.yon = 200.0;
- viewAngleCameraData.cameraData.viewPort.origin.x = -1.0;
- viewAngleCameraData.cameraData.viewPort.origin.y = 1.0;
- viewAngleCameraData.cameraData.viewPort.width = 2.0;
- viewAngleCameraData.cameraData.viewPort.height = 2.0;
- viewAngleCameraData.fov = 1.2;
- viewAngleCameraData.aspectRatioXToY = Display_GetImageAspectRatio();
-
- gDisplayCamera = Q3ViewAngleAspectCamera_New(&viewAngleCameraData);
-
- Q3View_SetCamera(gDisplayView, gDisplayCamera);
-
- // Create the light group
- gDisplayLightGroup = Q3LightGroup_New();
- Q3View_SetLightGroup(gDisplayView, gDisplayLightGroup);
-
- // Create the point light
- pointLightData.lightData.isOn = kQ3True;
- pointLightData.lightData.brightness = 5.0;
- pointLightData.lightData.color = white;
- pointLightData.castsShadows = kQ3True;
- pointLightData.attenuation = kQ3AttenuationTypeInverseDistance;
- pointLightData.location.x = 0.0;
- pointLightData.location.y = 0.0;
- pointLightData.location.z = 0.0;
-
- gDisplayPointLight = Q3PointLight_New(&pointLightData);
-
- Q3Group_AddObject(gDisplayLightGroup, gDisplayPointLight);
-
- // Create the illumination shader
- #if 1
- gDisplayIllumination = Q3PhongIllumination_New();
- #else
- gDisplayIllumination = Q3LambertIllumination_New();
- #endif
- }
-
-
- /* =============================================================================
- * Display_Exit (external)
- *
- * Takes down the window, disposes of the QD3D stuff.
- * ========================================================================== */
- void Display_Exit(
- void)
- {
- if (gDisplayHasRendered)
- {
- // Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- Q3View_Sync(gDisplayView);
- }
-
- #if USE_DRAW_SPROCKET
- if(gDisplayContext != NULL)
- {
- DSpContext_FadeGammaOut(NULL, NULL);
- DSpContext_Release(gDisplayContext);
- DSpContext_SetState(gDisplayContext, kDSpContextState_Active);
- DSpContext_FadeGammaIn(NULL, NULL);
-
- gDisplayContext = NULL;
- }
-
- DSpShutdown();
- #else
- if (gDisplayWindow != NULL)
- {
- DisposeWindow(gDisplayWindow);
- gDisplayWindow = NULL;
- }
- #endif
-
- if (gDisplayView != NULL)
- {
- Q3Object_Dispose(gDisplayView);
- gDisplayView = NULL;
- }
-
- if (gDisplayDrawContext != NULL)
- {
- Q3Object_Dispose(gDisplayDrawContext);
- gDisplayDrawContext = NULL;
- }
-
- if (gDisplayRenderer != NULL)
- {
- Q3Object_Dispose(gDisplayRenderer);
- gDisplayRenderer = NULL;
- }
-
- if (gDisplayCamera != NULL)
- {
- Q3Object_Dispose(gDisplayCamera);
- gDisplayCamera = NULL;
- }
-
- if (gDisplayLightGroup != NULL)
- {
- Q3Object_Dispose(gDisplayLightGroup);
- gDisplayLightGroup = NULL;
- }
-
- if (gDisplayAmbientLight != NULL)
- {
- Q3Object_Dispose(gDisplayAmbientLight);
- gDisplayAmbientLight = NULL;
- }
-
- if (gDisplayDirectionalLight != NULL)
- {
- Q3Object_Dispose(gDisplayDirectionalLight);
- gDisplayDirectionalLight = NULL;
- }
-
- if (gDisplayPointLight != NULL)
- {
- Q3Object_Dispose(gDisplayPointLight);
- gDisplayPointLight = NULL;
- }
-
- if (gDisplayIllumination != NULL)
- {
- Q3Object_Dispose(gDisplayIllumination);
- gDisplayIllumination = NULL;
- }
- }
-
-
- /* =============================================================================
- * Display_Activate (external)
- *
- * Handles activation and deactivation.
- * ========================================================================== */
- void Display_Activate(
- Boolean inActivate)
- {
- if (gDisplayActive != inActivate)
- {
- gDisplayActive = inActivate;
-
- Input_Activate(inActivate);
-
- if (!gDisplayActive)
- {
- Game_Silence();
- }
-
- if (gDisplayHasRendered)
- {
- // Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- Q3View_Sync(gDisplayView);
- }
-
- Display_DrawGrow();
- }
- }
-
-
- /* =============================================================================
- * Display_IsActive (external)
- *
- * Returns true if the game is active.
- * ========================================================================== */
- Boolean Display_IsActive(
- void)
- {
- #if USE_DRAW_SPROCKET
- return true;
- #else
- return gDisplayActive;
- #endif
- }
-
-
- /* =============================================================================
- * Display_DrawGrow (external)
- *
- * Draws the grow box.
- * ========================================================================== */
- void Display_DrawGrow(
- void)
- {
- #if !USE_DRAW_SPROCKET
- Rect bounds;
-
- SetPort(gDisplayWindow);
-
- // Erase the horizontal part
- bounds = gDisplayWindow->portRect;
- bounds.top = bounds.bottom-15;
-
- EraseRect(&bounds);
-
- // Draw the grow box, but only the horizontal scroll stuff
- ClipRect(&bounds);
- DrawGrowIcon(gDisplayWindow);
- ClipRect(&gDisplayWindow->portRect);
- #endif
- }
-
-
- /* =============================================================================
- * Display_DrawContents (external)
- *
- * Draws the contents of the window.
- * ========================================================================== */
- void Display_DrawContents(
- void)
- {
- TQ3Area area;
- FontInfo fontInfo;
- Rect bounds;
- Rect bounds1;
-
- static Str255 pausedString = "\pPaused"; //• SHOULD COME FROM RESOURCE
-
- switch (Game_GetState())
- {
- case kGameState_Playing:
- Display_RenderImage();
- break;
-
- case kGameState_Paused:
- Display_RenderImage();
- Display_BeginQD();
- Display_GetImageArea(&area);
-
- TextFont(kFontIDGeneva);
- TextFace(bold);
- TextSize(72);
-
- GetFontInfo(&fontInfo);
-
- MoveTo(
- area.min.x + 0.5*(area.min.x + area.max.x - StringWidth(pausedString)),
- area.min.y + 0.5*(area.min.y + area.max.y + fontInfo.ascent));
-
- ForeColor(redColor);
- DrawString(pausedString);
- ForeColor(blackColor);
-
- Display_EndQD();
- break;
-
- case kGameState_Stopped:
- Display_BeginQD();
-
- Display_GetImageArea(&area);
-
- bounds.top = area.min.y;
- bounds.left = area.min.x;
- bounds.bottom = area.max.y;
- bounds.right = area.max.x;
-
- PaintRect(&bounds);
-
- bounds1 = (*gDisplayStartScreen)->picFrame;
- OffsetRect(
- &bounds1,
- ((bounds.right-bounds.left) - (bounds1.right-bounds1.left) >> 1) - bounds1.left,
- ((bounds.bottom-bounds.top) - (bounds1.bottom-bounds1.top) >> 1) - bounds1.top);
-
- DrawPicture(gDisplayStartScreen, &bounds1);
-
- Display_EndQD();
- break;
- }
- }
-
-
- /* =============================================================================
- * Display_RenderImage (internal)
- *
- * Draws the 3D part of the window.
- * ========================================================================== */
- void Display_RenderImage(
- void)
- {
- Q3View_StartRendering(gDisplayView);
- do
- {
- // Set up the rendering state
- Q3InterpolationStyle_Submit(kQ3InterpolationStyleVertex, gDisplayView);
- Q3BackfacingStyle_Submit(kQ3BackfacingStyleFlip, gDisplayView);
- Q3FillStyle_Submit(kQ3FillStyleFilled, gDisplayView);
- Q3Object_Submit(gDisplayIllumination, gDisplayView);
-
- // Draw the game contents
- Game_Submit(gDisplayView);
- }
- while (Q3View_EndRendering(gDisplayView) == kQ3ViewStatusRetraverse);
-
- gDisplayHasRendered = true;
-
- #if USE_DRAW_SPROCKET
- // we don't need to swap buffers because we're single buffered
- #endif
- }
-
-
- /* =============================================================================
- * Display_Resize (external)
- *
- * Called after the window has changed size.
- * ========================================================================== */
- void Display_Resize(
- void)
- {
- #if !USE_DRAW_SPROCKET
- TQ3Area imageArea;
-
- // Reset the clip
- ClipRect(&gDisplayWindow->portRect);
-
- // Change the draw context
- Display_GetImageArea(&imageArea);
- Q3DrawContext_SetPane(gDisplayDrawContext, &imageArea);
-
- // Change the camera aspect ratio
- Q3ViewAngleAspectCamera_SetAspectRatio(gDisplayCamera, Display_GetImageAspectRatio());
- #endif
- }
-
-
- /* =============================================================================
- * Display_GetWindow (external)
- *
- * Returns our window pointer.
- * ========================================================================== */
- WindowPtr Display_GetWindow(
- void)
- {
- #if USE_DRAW_SPROCKET
- return NULL;
- #else
- return gDisplayWindow;
- #endif
- }
-
-
- /* =============================================================================
- * Display_SetViewerPosition (external)
- *
- * Moves the camera and point light based on the given info.
- * ========================================================================== */
- void Display_SetViewerPosition(
- const TQ3Point3D* inPosition,
- const TQ3Vector3D* inDirection,
- const TQ3Vector3D* inUp)
- {
- TQ3CameraPlacement placement;
-
- assert(inPosition != NULL);
- assert(inDirection != NULL);
- assert(inUp != NULL);
-
- // Move the camera
- placement.cameraLocation = *inPosition;
- placement.upVector = *inUp;
-
- Q3Point3D_Vector3D_Add(inPosition, inDirection, &placement.pointOfInterest);
-
- Q3Camera_SetPlacement(gDisplayCamera, &placement);
-
- // Move the point light
- Q3PointLight_SetLocation(gDisplayPointLight, inPosition);
- }
-
-
- /* =============================================================================
- * Display_GetViewerPosition (external)
- *
- * Returns the current camera position.
- * ========================================================================== */
- void Display_GetViewerPosition(
- TQ3Point3D* outPosition,
- TQ3Vector3D* outDirection,
- TQ3Vector3D* outUp)
- {
- TQ3CameraPlacement placement;
-
- assert(outPosition != NULL);
- assert(outDirection != NULL);
- assert(outUp != NULL);
-
- Q3Camera_GetPlacement(gDisplayCamera, &placement);
-
- *outPosition = placement.cameraLocation;
- *outUp = placement.upVector;
-
- Q3Point3D_Subtract(
- &placement.pointOfInterest,
- &placement.cameraLocation,
- outDirection);
- }
-
-
- /* =============================================================================
- * Display_GetImageArea (internal)
- *
- * Sets outArea to the area occupied by the 3D image part of the window.
- * ========================================================================== */
- void Display_GetImageArea(
- TQ3Area* outArea)
- {
- assert(outArea != NULL);
-
- #if USE_DRAW_SPROCKET
- {
- DSpContextAttributes attributes;
-
- DSpContext_GetAttributes(gDisplayContext, &attributes);
-
- outArea->min.x = 0;
- outArea->max.x = attributes.displayWidth;
- outArea->min.y = 0;
- outArea->max.y = attributes.displayHeight;
- }
- #else
- outArea->min.x = gDisplayWindow->portRect.left;
- outArea->max.x = gDisplayWindow->portRect.right;
- outArea->min.y = gDisplayWindow->portRect.top;
- outArea->max.y = gDisplayWindow->portRect.bottom-15;
- #endif
- }
-
-
- /* =============================================================================
- * Display_GetImageAspectRatio (internal)
- *
- * Returns the aspect ratio of the area occupied by the 3D image part of the
- * window.
- * ========================================================================== */
- float Display_GetImageAspectRatio(
- void)
- {
- TQ3Area imageArea;
-
- Display_GetImageArea(&imageArea);
-
- return (imageArea.max.x-imageArea.min.x) / (imageArea.max.y-imageArea.min.y);
- }
-
-
- /* =============================================================================
- * Display_BeginQD (internal)
- *
- * Sets up for doing Quickdraw drawing.
- * ========================================================================== */
- void Display_BeginQD(
- void)
- {
- if (gDisplayHasRendered)
- {
- // Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- Q3View_Sync(gDisplayView);
- }
-
- #if USE_DRAW_SPROCKET
- {
- CGrafPtr port;
-
- DSpContext_GetBackBuffer(gDisplayContext, kDSpBufferKind_Normal, &port);
- SetPort((GrafPtr) port);
- }
- #else
- SetPort(gDisplayWindow);
- #endif
- }
-
-
- /* =============================================================================
- * Display_EndQD (internal)
- *
- * Undoes what Display_BeginQD did.
- * ========================================================================== */
- void Display_EndQD(
- void)
- {
- #if USE_DRAW_SPROCKET
- // do nothing
- #else
- // do nothing
- #endif
- }
-
-
-